package com.tqw.client.service.impl;

import com.tqw.client.dao.ClientMapper;
import com.tqw.client.pojo.ImgResult;
import com.tqw.client.service.ClientFileService;
import com.tqw.entity.JWTUtil;
import com.tqw.pojo.Client;
import com.tqw.vo.ImageVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.tqw.client.pojo.Code.*;

/**
 * @author Will
 */
@Slf4j
@Service
public class ClientFileServiceImpl implements ClientFileService {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private ClientMapper clientMapper;


    //定义文件的根目录
    private String rootDir = "D:/test_image";
    //定义图片服务器网址
    private String rootURL = "http://avatar.tqw.com";
    /**
     * 上传头像
     * @param img
     * @return
     */
    @Override
    public ImgResult upload(MultipartFile img, String token) {
        if (img.getSize()==0){
            return new ImgResult().setCode(IS_EMPTY).setResultMessage("请选择图片").setToken(null);
        }
        if (img.getSize()>MAX_SIZE){
            return new ImgResult().setCode(TOO_BIG).setResultMessage("只能上传2M以内的图片").setToken(null);
        }

        //获取图片名称,全部转化为小写
        String fileName = img.getOriginalFilename().toLowerCase();
        if (!fileName.matches("^.+\\.(jpg|png|gif)$")){
            return new ImgResult().setCode(FORMAT_ERROR).setResultMessage("必须是.jpg/.png/.gif格式的图片").setToken(null);
        }
        //将检查异常,转化为运行时异常
        try {
            //2.通过校验宽度和高度判断是否为图片
            BufferedImage bufferedImage = ImageIO.read(img.getInputStream());
            int width = 0;
            int height = 0;
            try {
                width = bufferedImage.getWidth();
                height = bufferedImage.getHeight();
            } catch (NullPointerException e) {
                log.warn("NullPointerException:  {}","This file(img) has no width and height.");
                return new ImgResult().setCode(NO_IMG).setResultMessage("不正确的图片").setToken(null);
            }
            if (width == 0 || height == 0){
                return new ImgResult().setCode(NO_IMG).setResultMessage("该图片是空").setToken(null);
            }
            //3.实现分目录的存储
            String datePath = new SimpleDateFormat("/yyyy/MM/dd/")
                    .format(new Date());
            String fileDir = rootDir + datePath;
            File dirFile = new File(fileDir);
            if (!dirFile.exists()){
                dirFile.mkdirs();
            }
            //4.动态生成UUID
            String tqw = "TQW";
            String UUID = java.util.UUID.randomUUID().toString();
            int index = fileName.lastIndexOf(".");
            String fileType = fileName.substring(index);
            fileName =tqw + UUID + fileType;
            //5.实现文件上传  准备文件的全路径
            String path = fileDir + fileName;
            img.transferTo(new File(path));

            //6.准备ImageVO数据返回
            String virtualPath = datePath + fileName;
            String urlPath = rootURL + virtualPath ;
            log.debug("rootURL {}",rootURL);
            ImageVO imageVO = new ImageVO(virtualPath,urlPath,fileName);

            //7.从token获取id,把头像地址更新到数据库
            Integer id = JWTUtil.getId(token);
            clientMapper.updateAvatar(urlPath,id);

            Client client = JWTUtil.getClient(token).setAvatar(urlPath);
            redisTemplate.delete(token);
            //生成新的token
            token = JWTUtil.sign(JWTUtil.getMap(client));
            redisTemplate.opsForValue().set(token, String.valueOf(client.getId()));
            return new ImgResult(imageVO,token).setCode(SUCCESS).setResultMessage("上传成功");
        } catch (IOException e) {
            //一般条件下为了不影响代码结构,将检查异常,转化为运行时异常
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

}
